﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MethodWorx.Core.DomainModel
{
    public class StubUnitOfWork : IUnitOfWork
    {
        public StubUnitOfWork()
        {
        }

        public StubUnitOfWork(Dictionary<Type, string> uniqueKeyViolations)
        {
            this.uniqueKeyViolations = uniqueKeyViolations;
        }

        #region IUnitOfWork Members

        private bool open = true;
        private bool cancelled = false;
        private bool commited = false;

        private List<AggregateRoot> added = new List<AggregateRoot>();
        private List<AggregateRoot> deleted = new List<AggregateRoot>();
        private List<AggregateRoot> changed = new List<AggregateRoot>();
        private Dictionary<Type, string> uniqueKeyViolations = new Dictionary<Type, string>();

        public void Commit()
        {
            open = false;
            commited = true;
        }

        public void Cancel()
        {
            open = false;
            cancelled = true;
        }

        public bool IsOpen { get { return this.open;  } }
        public bool IsCommited { get { return this.commited; } }
        public bool IsCancelled { get { return this.cancelled; } }

        public void RegisterChanged<T>(T entity) where T : AggregateRoot
        {
            this.changed.Add(entity);
        }

        public void RegisterDeleted<T>(T entity) where T : AggregateRoot
        {
            this.deleted.Add(entity);
        }

        public void RegisterAdded<T>(T entity) where T : AggregateRoot
        {
            if(this.uniqueKeyViolations != null && this.uniqueKeyViolations.ContainsKey(typeof(T)))
                throw new UniqueKeyViolationException(this.uniqueKeyViolations[typeof(T)]);

            this.added.Add(entity);
        }

        public IEnumerable<AggregateRoot> Added { get { return this.added;  } }
        public IEnumerable<AggregateRoot> Deleted { get { return this.deleted; } }
        public IEnumerable<AggregateRoot> Changed { get { return this.changed; } }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
        }

        #endregion
    }
}
